Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slic open before flush #1387

Merged
merged 25 commits into from
Sep 18, 2024
Merged

Slic open before flush #1387

merged 25 commits into from
Sep 18, 2024

Conversation

bmhan12
Copy link
Contributor

@bmhan12 bmhan12 commented Jul 22, 2024

This PR:

  • Explores an alternative way to create Slic log streams to files. With the current Slic approach, files must be opened/created when the stream object is constructed. If no messages are logged, the file remains empty. If there is an error and Slic tells MPI to abort, all ranks will attempt to flush, with files remaining empty if the rank could not flush before the non-collective abort call and/or no messages have been logged on that rank.

  • Constructors were added to GenericOutputStream/LumberjackStream/SynchronizedStream that take in a std::string that is parsed and interpreted as std::cout, std:cerr, or a file name. In the case of a filename, the file is not opened until slic flushes and the stream has at least one message logged. This is done in LumberjackStream/SynchronizedStream by default constructing an std::ofstream object (no file has been opened yet), and delaying the open(filename) call until flushing. This is done in GenericOutputStream by initially constructing an std::ostringstream to buffer the messages in memory, and turning the std::ostringstream into a std::ofstream file when flushing.

- While these constructors work, I am not sure if it's the best way of addressing the current lack of file support in Slic. These std::string constructors take ownership of std::ostream from the user, which can be limiting if you want access to both the std::ostream object and the open-before-flush file behavior. In previous discussions, @gberg617 suggested adding getter methods to the in-memory messages storage (e.g. Lumberjack object in LumberjackStream, std::vector of messages in SynchronizedStream), so developers could take that information and create their own behavior. This would allow user-access to the std::ostream object and the open-before-flush file behavior with some effort. (Resolved. Can add getter method later to std::ostream object if needed for access when using string constructors).

@bmhan12 bmhan12 force-pushed the feature/han12/slic_open_on_write branch from 54de589 to 4a3cc79 Compare July 30, 2024 17:22
@bmhan12 bmhan12 marked this pull request as ready for review July 30, 2024 17:22
@bmhan12
Copy link
Contributor Author

bmhan12 commented Aug 26, 2024

This PR is ready for review, confirmed with @gberg617 that it is working for their use case.

@bmhan12 bmhan12 added the Slic Issues related to Axom's 'slic' component label Aug 26, 2024
Copy link
Member

@rhornung67 rhornung67 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @bmhan12 Looks good!

Comment on lines 52 to 57
*
* \note The constructed std::ofstream will open and associate a file with
* the stream the first time GenericOutputStream is flushed with at
* least one buffered message. Use this constructor
* to avoid empty file creation if GenericOutputStream is not appended
* to.
Copy link
Member

@agcapps agcapps Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note (and the one at new line 82) is hard to understand. Please rephrase. Consider dropping the first sentence and changing the second to something like "Use this constructor to avoid creating an empty file if this GenericOutputStream never gets a message."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Copy link
Member

@agcapps agcapps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working this through, Brian.

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @bmhan12 !

Please also update the RELEASE_NOTES about this change.

Comment on lines 111 to 122
std::ostringstream* oss = dynamic_cast<std::ostringstream*>(m_stream);
if(oss != nullptr)
{
std::string buffer = oss->str();
if(!buffer.empty())
{
delete m_stream;
m_stream = new std::ofstream(m_file_name);
(*m_stream) << buffer;
m_opened = true;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting approach!

It took me a moment to figure out why the delete/new is necessary.

Could you please add a brief comment that we're converting from the original ostringstream to an ofstream and writing the former's contents to the latter?

src/axom/slic/streams/SynchronizedStream.cpp Show resolved Hide resolved
src/axom/slic/tests/slic_macros.cpp Outdated Show resolved Hide resolved

EXPECT_EQ(with_fmt_buffer.str(), "Test");

// Cleanup generated files (not working Windows)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it known that this doesn't work on Windows?
I didn't see an issue for this -- if we don't have one, can you please create one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see an issue for this -- if we don't have one, can you please create one?

Opened an issue here: #1415
I didn't dive too deep into why it wasn't working on Windows for this specific case.
More generally though, there are multiple places where we call removeFile in the code but don't check the return value/check if file is really deleted.

@bmhan12 bmhan12 mentioned this pull request Sep 18, 2024
2 tasks
@bmhan12 bmhan12 merged commit 6ad3155 into develop Sep 18, 2024
13 checks passed
@bmhan12 bmhan12 deleted the feature/han12/slic_open_on_write branch September 18, 2024 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Slic Issues related to Axom's 'slic' component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants